package com.felix.thread;

import lombok.Data;

import java.io.IOException;
import java.util.concurrent.CyclicBarrier;

/**
 * CyclicBarrierDemo
 *
 * @author xuejinhua
 * @date 2018/9/27 14:36
 */
@Data
public class CyclicBarrierDemo implements Runnable {

    private String player;
    private CyclicBarrier barrier;

    public CyclicBarrierDemo(String player, CyclicBarrier barrier) {
        this.player = player;
        this.barrier = barrier;
    }

    @Override
    public void run() {
        try {
            System.out.println(this.getPlayer() + " 开始匹配玩家...");
            findOtherPlayer();
            barrier.await();

            System.out.println(this.getPlayer() + " 进行选择角色...");
            choiceRole();
            System.out.println(this.getPlayer() + " 角色选择完毕等待其他玩家...");
            barrier.await();

            System.out.println(this.getPlayer() + " 开始游戏,进行游戏加载...");
            loading();
            System.out.println(this.getPlayer() + " 游戏加载完毕等待其他玩家加载完成...");
            barrier.await();
            start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 匹配其他玩家
     */
    public void findOtherPlayer() throws InterruptedException {
        Thread.sleep((long) (1000 * Math.random()));
    }

    /**
     * 选择角色
     */
    public void choiceRole() throws InterruptedException {
        Thread.sleep((long) (3000 * Math.random()));
    }

    /**
     * 加载
     */
    public void loading() throws InterruptedException {
        Thread.sleep((long) (10000 * Math.random()));
    }

    /**
     * 开始
     */
    public void start() {
        System.out.println(this.getPlayer() + " 开始");
    }

    public static void main(String[] args) throws IOException {
//        CyclicBarrier barrier = new CyclicBarrier(5);
        CyclicBarrier barrier = new CyclicBarrier(5, () -> {
            try {
                System.out.println("阶段完成，等待2秒...");
                Thread.sleep(2000);
                System.out.println("进入下个阶段...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        });

        Thread player1 = new Thread(new CyclicBarrierDemo("1", barrier));
        Thread player2 = new Thread(new CyclicBarrierDemo("2", barrier));
        Thread player3 = new Thread(new CyclicBarrierDemo("3", barrier));
        Thread player4 = new Thread(new CyclicBarrierDemo("4", barrier));
        Thread player5 = new Thread(new CyclicBarrierDemo("5", barrier));

        player1.start();
        player2.start();
        player3.start();
        player4.start();
        player5.start();

    }
}
